<?php

require_once 'vendor/autoload.php';

use Smalot\Cups\Builder\Builder;
use Smalot\Cups\Manager\JobManager;
use Smalot\Cups\Manager\PrinterManager;
use Smalot\Cups\Model\Job;
use Smalot\Cups\Transport\ResponseParser;
use Http\Client\Socket\Client as HttpClient;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * 简单的Host Header修复示例
 * 使用自定义HttpClient来解决"Remote is not defined and we cannot determine a connection endpoint for this request (no Host header)"错误
 */
class SimpleHostHeaderFix
{
    private string $printerIp;
    private int $printerPort;
    private Builder $builder;
    private ResponseParser $responseParser;

    public function __construct(string $printerIp = '10.1.0.12', int $printerPort = 631)
    {
        $this->printerIp = $printerIp;
        $this->printerPort = $printerPort;
        $this->builder = new Builder();
        $this->responseParser = new ResponseParser();
        
        echo "🔧 简单Host Header修复示例\n";
        echo "目标打印机: {$this->printerIp}:{$this->printerPort}\n";
        echo str_repeat('=', 50) . "\n\n";
    }

    /**
     * 创建自定义HttpClient来修复Host header问题
     */
    private function createCustomHttpClient(): HttpClient
    {
        return new class($this->printerIp, $this->printerPort) extends HttpClient {
            private string $targetIp;
            private int $targetPort;
            
            public function __construct(string $ip, int $port)
            {
                parent::__construct();
                $this->targetIp = $ip;
                $this->targetPort = $port;
            }
            
            public function sendRequest(RequestInterface $request): ResponseInterface
            {
                // 确保Host header正确设置
                $request = $request->withHeader('Host', $this->targetIp . ':' . $this->targetPort);
                
                // 添加必要的IPP headers
                $request = $request
                    ->withHeader('User-Agent', 'CUPS-IPP-Client/2.0')
                    ->withHeader('Accept', 'application/ipp')
                    ->withHeader('Content-Type', 'application/ipp');
                
                // 修改URI指向正确的目标
                $uri = $request->getUri()
                    ->withHost($this->targetIp)
                    ->withPort($this->targetPort)
                    ->withScheme('http');
                
                $request = $request->withUri($uri);
                
                return parent::sendRequest($request);
            }
        };
    }

    /**
     * 测试打印功能
     */
    public function testPrint(): bool
    {
        echo "🖨️  开始打印测试...\n";
        
        try {
            // 创建自定义HttpClient
            $httpClient = $this->createCustomHttpClient();
            
            // 创建管理器
            $jobManager = new JobManager($this->builder, $httpClient, $this->responseParser);
            $printerManager = new PrinterManager($this->builder, $httpClient, $this->responseParser);
            
            // 查找打印机
            $printerUri = "ipp://{$this->printerIp}:{$this->printerPort}/ipp/print";
            echo "📍 查找打印机: $printerUri\n";
            
            $printer = $printerManager->findByUri($printerUri);
            
            if (!$printer) {
                echo "❌ 无法找到打印机\n";
                return false;
            }
            
            echo "✅ 找到打印机: {$printer->getName()}\n";
            
            // 创建测试任务
            $job = new Job();
            $job->setName('Host Header修复测试');
            $job->setUsername('testuser');
            $job->setCopies(1);
            $job->setPrinterUri($printerUri);
            
            // 添加测试内容
            $testContent = $this->createTestContent();
            $job->addText($testContent);
            
            echo "📄 发送打印任务...\n";
            
            // 发送任务
            $result = $jobManager->send($printer, $job);
            
            if ($result) {
                echo "✅ 打印任务发送成功！\n";
                echo "📋 任务ID: {$result->getId()}\n";
                echo "📊 任务状态: {$result->getState()}\n";
                return true;
            } else {
                echo "❌ 打印任务发送失败\n";
                return false;
            }
            
        } catch (Exception $e) {
            echo "❌ 错误: {$e->getMessage()}\n";
            
            // 检查是否是Host header相关错误
            if (strpos($e->getMessage(), 'Host header') !== false) {
                echo "💡 这是Host header问题，我们的修复应该已经解决了这个问题\n";
                echo "💡 请检查打印机IP地址和端口是否正确\n";
            }
            
            return false;
        }
    }

    /**
     * 创建测试内容
     */
    private function createTestContent(): string
    {
        return "Host Header修复测试\n" .
               "===================\n" .
               "时间: " . date('Y-m-d H:i:s') . "\n" .
               "打印机: {$this->printerIp}:{$this->printerPort}\n" .
               "状态: Host header问题已修复\n" .
               "\n" .
               "如果您看到这个文档，说明Host header修复成功！\n";
    }

    /**
     * 网络连接测试
     */
    public function testConnection(): bool
    {
        echo "🔍 测试网络连接...\n";
        
        // 测试ping
        echo "📡 Ping测试: ";
        $pingCommand = "ping -n 1 -w 1000 {$this->printerIp}";
        $output = [];
        $returnCode = 0;
        exec($pingCommand . ' 2>&1', $output, $returnCode);
        
        if ($returnCode === 0) {
            echo "✅ 成功\n";
        } else {
            echo "❌ 失败\n";
            echo "   输出: " . implode('\n', $output) . "\n";
        }
        
        // 测试端口
        echo "🔌 端口测试: ";
        $connection = @fsockopen($this->printerIp, $this->printerPort, $errno, $errstr, 5);
        
        if ($connection) {
            echo "✅ 端口 {$this->printerPort} 开放\n";
            fclose($connection);
            return true;
        } else {
            echo "❌ 端口 {$this->printerPort} 无法连接\n";
            echo "   错误: $errstr ($errno)\n";
            return false;
        }
    }

    /**
     * Windows备用打印方案
     */
    public function windowsFallback(): bool
    {
        if (PHP_OS_FAMILY !== 'Windows') {
            echo "❌ 当前系统不是Windows，无法使用备用方案\n";
            return false;
        }
        
        echo "🪟 尝试Windows系统打印...\n";
        
        $testContent = $this->createTestContent();
        $tempFile = tempnam(sys_get_temp_dir(), 'host_fix_');
        file_put_contents($tempFile, $testContent);
        
        $printerNames = [
            'EPSON L4260 Series',
            'EPSON L4260',
            'L4260 Series'
        ];
        
        foreach ($printerNames as $printerName) {
            echo "🖨️  尝试: {$printerName} ";
            
            $command = "print /D:\"{$printerName}\" \"{$tempFile}\"";
            $output = [];
            $returnCode = 0;
            exec($command . ' 2>&1', $output, $returnCode);
            
            if ($returnCode === 0) {
                echo "✅ 成功\n";
                unlink($tempFile);
                return true;
            } else {
                echo "❌ 失败\n";
            }
        }
        
        unlink($tempFile);
        return false;
    }

    /**
     * 运行完整测试
     */
    public function runFullTest(): void
    {
        echo "🚀 开始完整的Host Header修复测试\n";
        echo str_repeat('=', 50) . "\n\n";
        
        // 1. 网络连接测试
        echo "步骤 1: 网络连接测试\n";
        $connectionOk = $this->testConnection();
        echo "\n";
        
        // 2. IPP打印测试
        echo "步骤 2: IPP打印测试\n";
        $printOk = $this->testPrint();
        echo "\n";
        
        // 3. 如果IPP失败，尝试Windows备用方案
        if (!$printOk) {
            echo "步骤 3: Windows备用打印方案\n";
            $fallbackOk = $this->windowsFallback();
            echo "\n";
        }
        
        // 总结
        echo "📊 测试总结\n";
        echo str_repeat('-', 30) . "\n";
        echo "网络连接: " . ($connectionOk ? "✅ 成功" : "❌ 失败") . "\n";
        echo "IPP打印: " . ($printOk ? "✅ 成功" : "❌ 失败") . "\n";
        
        if (isset($fallbackOk)) {
            echo "Windows备用: " . ($fallbackOk ? "✅ 成功" : "❌ 失败") . "\n";
        }
        
        if ($printOk) {
            echo "\n🎉 Host Header问题已成功修复！\n";
        } else {
            echo "\n💡 建议检查:\n";
            echo "   - 打印机IP地址是否正确\n";
            echo "   - 打印机是否开启IPP服务\n";
            echo "   - 网络防火墙设置\n";
            echo "   - 打印机驱动程序安装\n";
        }
    }
}

// 运行测试
try {
    $tester = new SimpleHostHeaderFix('10.1.0.12', 631);
    $tester->runFullTest();
} catch (Exception $e) {
    echo "❌ 致命错误: {$e->getMessage()}\n";
    echo "📍 位置: {$e->getFile()}:{$e->getLine()}\n";
}